package com.jesse.custom.component;

import com.jesse.util.ViewUtil;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.ScrollView;
import android.widget.Scroller;
 
public class FlowScrollView extends ScrollView{
	private static final String tag="LazyScrollView";
	private Handler handler;
	private View view;
	float mFirstX = 0;
    float mFirstY = 0;
    float endY = 0;
    private Context context;
	private int currentHight = 0;
	private int mTouchSlop = 0;
	private int mMinimumVelocity = 0;
	private int mMaximumVelocity  = 0;
	private VelocityTracker mVelocityTracker = null;
	private Scroller mScroller;
	public FlowScrollView(Context context) {
		super(context);
		this.context = context;
	}
	public FlowScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
	}
	public FlowScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.context = context;
	}
	//这个获得总的高度
	public int computeVerticalScrollRange(){
		return super.computeHorizontalScrollRange();
	}
	public int computeVerticalScrollOffset(){
		return super.computeVerticalScrollOffset();
	}
	
	 /**
     * 获得参考的View，主要是为了获得它的MeasuredHeight，然后和滚动条的ScrollY+getHeight作比较。
     */
    public void getView(){
    	this.view=getChildAt(0);
    	if(view!=null){
    		init();
    	}
    }
    
	private void init(){
		
		this.setOnTouchListener(onTouchListener);
		handler=new Handler(){
        	@Override
			public void handleMessage(Message msg) {
				// process incoming messages here
				super.handleMessage(msg);
				switch(msg.what){
				case 1:
					
					if(view.getMeasuredHeight() <= getScrollY() + getHeight()) {
						if(onScrollListener!=null){
							onScrollListener.onBottom();
						}
						
					}else if(getScrollY()==0){
						if(onScrollListener!=null){
							onScrollListener.onTop();
						}
					}
					else{
						if(onScrollListener!=null){
							onScrollListener.onScroll();
						}
					}
					break;
				default:
					break;
				}
			}
        };
		
        mScroller = new Scroller(getContext());
        setFocusable(true);
        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
        setWillNotDraw(false);
        
        final ViewConfiguration configuration = ViewConfiguration.get(context);
        mTouchSlop = configuration.getScaledTouchSlop();
        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
	}
	
	  OnTouchListener onTouchListener=new OnTouchListener(){

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					currentHight = getScrollY();
					if (!mScroller.isFinished()) {
                        mScroller.abortAnimation();
					}
					break;
				case MotionEvent.ACTION_UP:
					if(view!=null && onScrollListener!=null){
						handler.sendMessageDelayed(handler.obtainMessage(1), 200);
					}
					
					break;

				default:
					break;
				}
				return false;
			}
	    	
	    };
	    
	    @Override
	    public void fling(int velocityY) {
	        if (getChildCount() > 0) {
	        		mScroller.fling(getScrollX(), getScrollY(), 0, velocityY, 0, 0, 0, currentHight + 3000);
	                final boolean movingDown = velocityY > 0;
	                invalidate();
	        }
	    }
	    
	    private void obtainVelocityTracker(MotionEvent event) {
	        if (mVelocityTracker == null) {
	                mVelocityTracker = VelocityTracker.obtain();
	        }
	        mVelocityTracker.addMovement(event);
	    }
	    
	    private void releaseVelocityTracker() {
	        if (mVelocityTracker != null) {
	                mVelocityTracker.recycle();
	                mVelocityTracker = null;
	        }
	    }
	    
	    @Override
	    public boolean onInterceptTouchEvent(MotionEvent ev) {
	    	float lastX = ev.getX();
	        float lastY = ev.getY();
	        switch (ev.getAction()) {
	        case MotionEvent.ACTION_DOWN:
	            mFirstX = lastX;
	            mFirstY = lastY;
	            break;
	            
	        case MotionEvent.ACTION_MOVE:
	            float dx = lastX - mFirstX;
	            float dy = lastY - mFirstY;
	            
	            if (Math.abs(dx) >= 3 || Math.abs(dy) >= 3) {
	            	return true;
	            } else {
	            	return false;  
	            }
	        }
			return super.onInterceptTouchEvent(ev);
	    }
	    
	    @Override  
	    public boolean onTouchEvent(MotionEvent ev) {  
	    	obtainVelocityTracker(ev);

	    	float lastX = ev.getX();
	        float lastY = ev.getY();
	        switch (ev.getAction()) {
	        case MotionEvent.ACTION_DOWN:
	           
	            break;
	            
	        case MotionEvent.ACTION_MOVE:
	            float dx = lastX - mFirstX;
	            endY = lastY - mFirstY;
	            this.scrollTo(0, (int) (-endY + currentHight));
            	return true;
            	
	        case MotionEvent.ACTION_UP:
	        	currentHight = getScrollY();
	        	final VelocityTracker velocityTracker = mVelocityTracker;
	        	velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
	        	int initialVelocity = (int) velocityTracker.getYVelocity();
	        	if ((Math.abs(initialVelocity) > mMinimumVelocity) && getChildCount() > 0) {
	        		fling(-initialVelocity);
	        	}
	        	releaseVelocityTracker();
	        	break;
	        }
	        return super.onTouchEvent(ev);  
	    }  
	    
	    class MoveHandler extends Handler {
	    	 @Override
	         public void handleMessage(Message msg) {
	             super.handleMessage(msg);
	             
	             int fromY = currentHight;
	                int toY = currentHight + 100;
	                currentHight = currentHight + 100;
	                int stepX = (int)((toY - fromY) * 10 * 1.0 / 1000);
	                FlowScrollView.this.smoothScrollTo(0, currentHight);
		        	
		        	fromY += stepX;
		        	FlowScrollView.this.scrollTo(fromY, 0);
		            invalidate();
		            this.sendEmptyMessageDelayed(0, 10);
	    	 }
	    }
	    
	    public void computeScroll() {
	        if (mScroller.computeScrollOffset()) {
	                int scrollX = getScrollX();
	                int scrollY = getScrollY();
	                int oldX = scrollX;
	                int oldY = scrollY;
	                int x = mScroller.getCurrX();
	                int y = mScroller.getCurrY();
	                scrollX = x;
	                scrollY = y;
	                scrollY = scrollY + 10;
	                currentHight = scrollY;
	                scrollTo(scrollX, scrollY);
	                postInvalidate();
	        }
	}
	    
	    /**
	     * 定义接口
	     * @author admin
	     *
	     */
	    public interface OnScrollListener{
	    	void onBottom();
	    	void onTop();
	    	void onScroll();
	    }
	    private OnScrollListener onScrollListener;
	    public void setOnScrollListener(OnScrollListener onScrollListener){
	    	this.onScrollListener=onScrollListener;
	    }
}
